<template>
  <div
    v-if="state.showVerticalDivider"
    class="divider-wrapper divider-vertical"
    @click="handleSplit"
    @mouseenter="handleMouseEnter('vertical')"
    @mouseleave="handleMouseLeave"
  >
    <div class="divider"></div>
  </div>
  <div
    v-if="state.showHorizontalDivider"
    class="divider-wrapper divider-horizontal"
    @click="handleSplitRow"
    @mouseenter="handleMouseEnter('horizontal')"
    @mouseleave="handleMouseLeave"
  >
    <div class="divider"></div>
  </div>

  <div v-if="state.showDividerLine" class="divider-line" :style="state.dividerStyle"></div>
</template>

<script>
import { reactive, watch } from 'vue'
import { extend } from '@opentiny/vue-renderless/common/object'
import { getCurrent, updateRect } from './container'

const LEGAL_DIVIDER_COMPONENT = ['CanvasRow', 'CanvasCol']

const ROW_SNIPPET = {
  componentName: 'CanvasRow',
  props: {
    rowGap: '20px',
    colGap: '20px'
  },
  children: [
    {
      componentName: 'CanvasCol',
      props: {
        rowGap: '20px',
        colGap: '20px',
        grow: true,
        shrink: true,
        widthType: 'auto'
      },
      children: []
    }
  ]
}

const COL_SNIPPET = {
  componentName: 'CanvasCol',
  props: {
    rowGap: '20px',
    colGap: '20px',
    grow: true,
    shrink: true,
    widthType: 'auto'
  },
  children: []
}

export default {
  props: {
    selectState: {
      type: Object,
      default: () => ({})
    }
  },
  setup(props) {
    const state = reactive({
      horizontalLeft: 0,
      horizontalTop: 0,
      verLeft: 0,
      verTop: 0,
      showVerticalDivider: false,
      showHorizontalDivider: false,
      showDividerLine: false,
      dividerStyle: {}
    })

    const handleSplit = () => {
      const { parent, schema } = getCurrent()

      const index = parent.children.findIndex(({ id }) => id === schema.id)

      parent.children.splice(index + 1, 0, extend(true, {}, COL_SNIPPET))
      updateRect()
    }

    const handleSplitRow = () => {
      const { parent, schema } = getCurrent()

      const index = parent.children.findIndex(({ id }) => id === schema.id)

      if (schema.componentName === 'CanvasRow') {
        parent.children.splice(index + 1, 0, extend(true, {}, ROW_SNIPPET))

        return
      }

      // 当前选中组件是 CanvasCol 横向切割
      if (schema.componentName === 'CanvasCol') {
        // 当前组件为空组件，直接切成两行
        if (!schema.children?.length) {
          schema.children = [extend(true, {}, ROW_SNIPPET), extend(true, {}, ROW_SNIPPET)]
        } else if (schema.children[0].componentName !== 'CanvasRow') {
          // 当前组件不为空组件且第一个孩子不为 row，则是第一次切割，切割成两行，需要将原来有的 children 放置到第一个 row 的 col
          schema.children = [
            {
              ...extend(true, {}, ROW_SNIPPET),
              children: [
                {
                  ...extend(true, {}, COL_SNIPPET),
                  children: [...(schema.children || [])]
                }
              ]
            },
            extend(true, {}, ROW_SNIPPET)
          ]
        } else {
          // 已经切割过了，直接加一行
          schema.children.push(extend(true, {}, ROW_SNIPPET))
        }
      }

      updateRect()
    }

    watch(
      () => props.selectState,
      (selectState) => {
        const { width, height, left, top, componentName } = selectState

        if (!LEGAL_DIVIDER_COMPONENT.includes(componentName)) {
          state.showHorizontalDivider = false
          state.showVerticalDivider = false

          return
        }

        state.showHorizontalDivider = true
        state.showVerticalDivider = 'CanvasRow' !== componentName

        const centerLeft = left + width / 2
        const centerTop = top + height / 2

        state.verLeft = `${centerLeft}px`
        state.verTop = `${top}px`

        state.horizontalLeft = `${left}px`
        state.horizontalTop = `${centerTop}px`
      },
      { deep: true }
    )

    // 鼠标进入剪刀按钮，出现剪刀线
    const handleMouseEnter = (type) => {
      const { width, height, left, top } = props.selectState
      if (type === 'vertical') {
        state.dividerStyle = {
          width: '1px',
          height: `${height}px`,
          left: `${state.verLeft}px`,
          top: `${top}px`
        }
      } else {
        state.dividerStyle = {
          width: `${width}px`,
          height: '1px',
          left: `${left}px`,
          top: `${state.horizontalTop}px`
        }
      }
      state.showDividerLine = true
    }

    const handleMouseLeave = () => {
      state.showDividerLine = false
      state.dividerStyle = {}
    }

    return {
      state,
      handleSplit,
      handleSplitRow,
      handleMouseEnter,
      handleMouseLeave
    }
  }
}
</script>

<style lang="less" scoped>
.divider-wrapper {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--ti-lowcode-common-text-color-3);
  cursor: pointer;
  z-index: 3;
  &.divider-vertical {
    transform: translateX(-50%);
    top: v-bind('state.verTop');
    left: v-bind('state.verLeft');
  }
  &.divider-horizontal {
    transform: translate(10px, -50%) rotate(270deg);
    top: v-bind('state.horizontalTop');
    left: v-bind('state.horizontalLeft');
  }
  &:hover {
    background-color: var(--ti-lowcode-common-primary-color);
    .divider {
      background-image: url();
    }
  }
  .divider {
    width: 12px;
    height: 12px;
    color: var(--ti-lowcode-common-text-color-3);
    background-size: contain;
    background-repeat: no-repeat;
    background-image: url();
  }
}

.divider-line {
  position: absolute;
  border: 1px dashed var(--ti-lowcode-common-primary-color);
  z-index: 2;
}
</style>
